package com.mexcad.db.connectors;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.lowagie.text.Element;
import com.mexcad.db.dto.CargoPago;
import com.mexcad.db.dto.CatPeriodoSolicitado;
import com.mexcad.db.dto.Cliente;
import com.mexcad.db.dto.Credito;
import com.mexcad.db.dto.Ejecutivo;
import com.mexcad.db.dto.Renta;
import com.mexcad.db.utils.HibernateUtil;
import com.mexcad.reports.utils.DataType;
import com.mexcad.utils.Constantes;
import com.mexcad.utils.Formatter;

import org.hibernate.criterion.*;

public class ReportConnectors {
	private static Log logger = LogFactory.getLog(CreditoConnector.class);
	
	private static final String ADDHOUR=" 00:00:00";
	
	private static String convierteFechaToSystem(String fecha){
		return Formatter.formateaFechaAAAAMMDD(fecha);
		//return fecha;
	}
	
	
	//Colocaci�n Cartera
	public static List<Credito> getAllCreditosByPeriodo(String fechaIni, String fechaFin) throws ParseException{
		logger.debug("Querying Creditos Reports");
		
		Session session = HibernateUtil.getSessionFactory().openSession();
		List <Credito>lista=null;
			
		try{
			fechaIni=fechaIni+ADDHOUR;
			fechaFin=fechaFin+ADDHOUR;
			
			logger.debug("Querying reports");
	
			
			 Criteria crit = session.createCriteria(Credito.class);
			 
			 DateFormat format = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
			 Date startDate = (Date)format.parse(fechaIni);
			 Date endDate =   (Date)format.parse(fechaFin);
			 crit.add(Expression.eq("idEstatus", new Integer(CreditoConnector.CREDITO_ACTIVO)));
			 crit.add(Expression.between("fechaInicial", new Date(startDate.getTime()), 
				    		   									   new Date(endDate.getTime()))); // Between date condition
			 System.out.println("&%&%&"+crit.toString());
			 lista = crit.list();
			
			session.close();
			
		}catch(org.hibernate.exception.GenericJDBCException excepts){
			if(session!= null)
				session.close();
			
		}catch(Exception e){
			e.printStackTrace();
			if(session!= null)
				session.close();
			
		} finally{

			if(session!= null && session.isOpen())
				session.close();
			
		}
		
		
		return lista;	
	}

	
	public static List<Credito> getAllCreditosByPeriodoAndEsquemaCredito(String fechaInicial, String fechaFinal, 
								int especial, int unam, int normaliva,int normal,int especialFinal, int entregasParciales, int unamIva  ){
		
		List <Credito>lista=null;
		Session session = HibernateUtil.getSessionFactory().openSession();

		try{
			fechaInicial=convierteFechaToSystem(fechaInicial)+ADDHOUR;
			fechaFinal=convierteFechaToSystem(fechaFinal)+ADDHOUR;
			
			logger.debug("Querying Creditos Reports");
			
			Criteria crit = session.createCriteria(Credito.class);
			 
			 DateFormat format = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
		
			
			String query =" from Credito as c where c.fechaInicial >='"+fechaInicial+"' AND c.fechaInicial <='"+ fechaFinal +"' ";
			query+=" AND(c.ckCredito.idEsquemaCredito ="+especial;
			query+=" OR c.ckCredito.idEsquemaCredito ="+unam;
			query+=" OR c.ckCredito.idEsquemaCredito ="+normaliva;
			query+=" OR c.ckCredito.idEsquemaCredito ="+normal;
			query+=" OR c.ckCredito.idEsquemaCredito ="+especialFinal;
			query+=" OR c.ckCredito.idEsquemaCredito ="+entregasParciales;
			query+=" OR c.ckCredito.idEsquemaCredito ="+unamIva+" ) AND idEstatus="+CreditoConnector.CREDITO_ACTIVO;
			query+=" order by c.ckCredito.idCliente,  ckCredito.idCredito asc";
			
			
			lista=session.createQuery(query).list();
			session.close();
		}catch(org.hibernate.exception.GenericJDBCException excepts){
			if(session!= null)
				session.close();
			
		}catch(Exception e){
			if(session!= null)
				session.close();
			
		} finally{
			if(session!= null && session.isOpen())
				session.close();
			
		}
			
		return lista;	
	}
	//Fin COnsultas COlocaci�n Cartera
	
	//Consultas para abono a cr�ditos
	//TODO fecha de registro.

	public static List getAllPagosPagosAnticipados(String fechaInicial, String fechaFinal){
		logger.debug("Querying  Pagos Pagos Anticipados Reports");
		
		Session session = HibernateUtil.getSessionFactory().openSession();
		List<Object []>lista=null;

		
		
		
		try{
			fechaInicial=convierteFechaToSystem(fechaInicial)+ADDHOUR;
			fechaFinal=convierteFechaToSystem(fechaFinal)+ADDHOUR;
			
			logger.debug("Querying Creditos Reports");
			
			String query ="SELECT  c.idCredito, c.nombres, c.apellidopaterno, c.apellidomaterno, c.montocredito, c.montoporperiodo, c.montototal, " +
						  "c.fechainicial, c.fechafinal, c.fecharegistrofinal,  cp.espago, cp.monto as montopago, cp.cargo as cargoporPago," +
						  "cp.abono as abono, cp.capital, cp.intereses, cp.impuestos, cp.otros from credito c "+
						  "inner join cargopago cp on c.idcredito = cp.idcredito where c.idestatus ="+CreditoConnector.CREDITO_PAGO_ANTICIPADO +" AND cp.fechaRegistro >='"+fechaInicial+"' AND cp.fechaRegistro <='"+ fechaFinal +"' "+
						  " order by c.idCliente asc";
						  	
			lista =session.createSQLQuery(query).list();
	
			session.close();
	
			
		}catch(org.hibernate.exception.GenericJDBCException excepts){
			if(session!= null&& session.isOpen())
				session.close();
			
		}catch(Exception e){
			if(session!= null&& session.isOpen())
				session.close();
			
		} finally{
			if(session!= null && session.isOpen())
				session.close();
			
		}
		
		
		return lista;	

	}

	
	
	public static List getAllCargosCreditosDeCargoPagoByPeriodo(String fechaInicial, String fechaFinal){
		Session session = HibernateUtil.getSessionFactory().openSession();
		List resp=null;
		try{	
				fechaInicial=convierteFechaToSystem(fechaInicial)+ADDHOUR;
				fechaFinal=convierteFechaToSystem(fechaFinal)+ADDHOUR;
				
				logger.debug("Querying Creditos Reports");
				String query ="SELECT DISTINCT (idrenta), idcredito FROM CargoPago AS c where c.fecharegistro >='"+fechaInicial+"' AND c.fecharegistro <='"+ fechaFinal +"' AND c.esPago=false order by idCredito asc";
				resp =session.createSQLQuery(query).list();
		
				session.close();
		}catch(org.hibernate.exception.GenericJDBCException excepts){
			if(session!= null)
				session.close();
			
		}catch(Exception e){
			if(session!= null)
				session.close();
			
		} finally{
			if(session!= null && session.isOpen())
				session.close();
			
		}			
			return resp;	
	}

	
	/**
	 * @return obtiene un List de arreglos de 2 elementos Object[0] tiene idRenta y Object[1] tiene idCredito
	 */
	public static List getAllRentasCreditosDeCargoPagoByPeriodo(String fechaInicial, String fechaFinal){
		Session session = HibernateUtil.getSessionFactory().openSession();
		List resp=null;
		try{	
				fechaInicial=convierteFechaToSystem(fechaInicial)+ADDHOUR;
				fechaFinal=convierteFechaToSystem(fechaFinal)+ADDHOUR;
				
				logger.debug("Querying Creditos Reports");
				String query ="SELECT DISTINCT (idrenta), idcredito FROM CargoPago AS c where c.fecharegistro >='"+fechaInicial+"' AND c.fecharegistro <='"+ fechaFinal +"' AND c.esPago=true order by idCredito asc";
				resp =session.createSQLQuery(query).list();
		
				session.close();
		}catch(org.hibernate.exception.GenericJDBCException excepts){
			if(session!= null)
				session.close();
			
		}catch(Exception e){
			if(session!= null)
				session.close();
			
		} finally{
			if(session!= null && session.isOpen())
				session.close();
			
		}			
			return resp;	
	}

	public static Renta getRentaPorId(Integer idRenta){
		return CreditoConnector.getRentaPorId(idRenta.intValue());
	}
	

	public static List<CargoPago> consultaPagosParaRentaCredito(int idRenta,int idCredito, 
																String fechaIni, String fechaFin){
		Session session = HibernateUtil.getSessionFactory().openSession();
		List<CargoPago>pagos=null;
		try{
			fechaIni=convierteFechaToSystem(fechaIni)+ADDHOUR;
			fechaFin=convierteFechaToSystem(fechaFin)+ADDHOUR;
			
			logger.debug("Querying consultaPagosParaRentaCredito");
			String query = "FROM CargoPago cp WHERE cp.ckCargoPago.idCredito="+idCredito+" AND cp.ckCargoPago.idRenta="+idRenta+" AND ";
			query+=" cp.fechaRegistro BETWEEN '"+fechaIni+"' AND '"+fechaFin+"' AND cp.idEstatus > 0 AND cp.esPago=true order by cp.ckCargoPago.idRenta, numCargoPago asc";
			
			pagos= session.createQuery(query).list();
			session.close();
		}catch(org.hibernate.exception.GenericJDBCException excepts){
			if(session!= null)
				session.close();
			
		}catch(Exception e){
			if(session!= null)
				session.close();
			
		} finally{
			if(session!= null && session.isOpen())
				session.close();
			
		}	
		return pagos;
		
	}
	
	
	public static List<CargoPago> consultaCargosParaRentaCredito(int idRenta,int idCredito, 
																String fechaIni, String fechaFin){
		Session session = HibernateUtil.getSessionFactory().openSession();
		List<CargoPago>pagos=null;
		try{
			fechaIni=convierteFechaToSystem(fechaIni)+ADDHOUR;
			fechaFin=convierteFechaToSystem(fechaFin)+ADDHOUR;
			
			logger.debug("Querying consultaPagosParaRentaCredito");
			String query = "FROM CargoPago cp WHERE cp.ckCargoPago.idCredito="+idCredito+" AND cp.ckCargoPago.idRenta="+idRenta+" AND ";
			query+=" cp.fechaRegistro BETWEEN '"+fechaIni+"' AND '"+fechaFin+"' AND cp.idEstatus > 0 AND cp.esPago=false order by cp.ckCargoPago.idRenta, numCargoPago asc";
			
			pagos= session.createQuery(query).list();
			session.close();
		}catch(org.hibernate.exception.GenericJDBCException excepts){
			if(session!= null)
				session.close();
			
		}catch(Exception e){
			if(session!= null)
				session.close();
			
		} finally{
			if(session!= null && session.isOpen())
				session.close();
			
		}	
		return pagos;
		
	}
	//Fin Consultas para abono a cr�ditos
	
	//Consultas para pagos anticipados
	//fin pagos anticiapados
	
	//Inicio de pagos vencidos todas las rentas que no se han pagado y estan activas
	
	public static List<Object[]> getIdsCreditosRentasNoPagadasActivas(String fechaIni, String fechaFin) throws ParseException{
		logger.debug("Querying Creditos Reports");
		
		Session session = HibernateUtil.getSessionFactory().openSession();
		List<Object []>lista=null;
			
		try{
			fechaIni=convierteFechaToSystem(fechaIni)+ADDHOUR;
			fechaFin=convierteFechaToSystem(fechaFin)+ADDHOUR;
			
			logger.debug("Querying Creditos Reports");
			String query ="SELECT DISTINCT (r.idCredito), r.idRenta, c.idEsquemaCredito, c.idEjecutivo, " +
					" c.apellidoPaterno ||' '|| c.apellidoMaterno ||' '|| c.nombres, c.idCliente, r.numRenta, " +
						  " r.fechaExigible, r.cargo,  r.saldo, c.idEsquemaCredito FROM Renta r inner join Credito c on c.idCredito=r.idCredito where r.fechaExigible >='"+fechaIni+"' AND r.fechaExigible <='"+ fechaFin +
						  "' AND r.idEstatus="+CreditoConnector.RENTA_ACTIVA+" AND c.idEstatus="+CreditoConnector.CREDITO_ACTIVO +"  order by r.idCredito asc";
			lista =session.createSQLQuery(query).list();
	
			session.close();
	
			
		}catch(org.hibernate.exception.GenericJDBCException excepts){
			if(session!= null&& session.isOpen())
				session.close();
			
		}catch(Exception e){
			if(session!= null&& session.isOpen())
				session.close();
			
		} finally{
			if(session!= null && session.isOpen())
				session.close();
			
		}
		
		
		return lista;	
	}

	

	//Fin de pagos vencidos
	
	
	//Inicio cuentas por cobrar Todos los que faltan por cobrar de todos los cr�ditos
	//Criterio por fecha de creacion.
	public static List<Credito> getAllCreditosCuentasPorCobrarByPeriodo(String fechaIni, String fechaFin) throws ParseException{
		logger.debug("Querying Creditos Reports");
		
		Session session = HibernateUtil.getSessionFactory().openSession();
		List <Credito>lista=null;
			
		try{
			fechaIni=fechaIni+ADDHOUR;
			fechaFin=fechaFin+ADDHOUR;
			
			logger.debug("Querying reports");
	
			
			 Criteria crit = session.createCriteria(Credito.class);
			 
			 DateFormat format = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
			 Date startDate = (Date)format.parse(fechaIni);
			 Date endDate =   (Date)format.parse(fechaFin);
			 crit.add(Expression.eq("idEstatus", new Integer(CreditoConnector.CREDITO_ACTIVO)));
			 crit.add(Expression.between("fechaCreacion", new Date(startDate.getTime()), 
				    		   									   new Date(endDate.getTime()))); // Between date condition
			 lista = crit.list();
			
			session.close();
			
		}catch(org.hibernate.exception.GenericJDBCException excepts){
			if(session!= null)
				session.close();
			
		}catch(Exception e){
			if(session!= null)
				session.close();
			
		} finally{
			if(session!= null && session.isOpen())
				session.close();
			
		}
		
		
		return lista;	
	}

	
	//fin de cuentas por cobrar

	//Inicio Comisiones 
	public static List<Object []> getPagosByPeriodoForComisions(String fechaIni, String fechaFin){
logger.debug("Querying Creditos Reports");
		
		Session session = HibernateUtil.getSessionFactory().openSession();
		List<Object []>lista=null;
			
		try{
			fechaIni=convierteFechaToSystem(fechaIni)+ADDHOUR;
			fechaFin=convierteFechaToSystem(fechaFin)+ADDHOUR;
			
			logger.debug("Querying Creditos Reports");
			String query ="SELECT DISTINCT (cp.idRenta), c.idCliente, cp.idCredito, cp.fechaRegistro as fechaAplicacion,  " +
						  "  cp.abono as pago,cp.intereses, "+
						  "	cl.comisionmexcad, cl.comisiongerente, cl.comisionacreedor,  c.idEsquemaCredito "+
						  " FROM CargoPago cp " +
						  " inner join Credito c  on c.idCredito=cp.idCredito " +
						  " inner join Renta   r  on r.idRenta = cp.idRenta "+
						  " inner join Cliente cl on c.idCliente=cl.idCliente "+
						  " where cp.fechaRegistro >='"+fechaIni+"' AND cp.fechaRegistro <='"+ fechaFin +
						  "' AND cp.idEstatus > 0 AND c.idEstatus="+CreditoConnector.CREDITO_ACTIVO +"  order by c.idCliente asc";
		
			lista =session.createSQLQuery(query).list();
	
			session.close();
	
			
		}catch(org.hibernate.exception.GenericJDBCException excepts){
			if(session!= null&& session.isOpen())
				session.close();
			
		}catch(Exception e){
			if(session!= null&& session.isOpen())
				session.close();
			
		} finally{
			if(session!= null && session.isOpen())
				session.close();
			
		}
		
		
		return lista;	
	}
	
	
	// fin Comisiones.
	
	// Consultas Catalogos
	public static Object[] getAllPeriodoSolicitado(){
		List <CatPeriodoSolicitado>lista=CatalogosConnector.getAllPeriodoSolicitadoReport();
		if(lista==null){
			lista=CatalogosConnector.getAllPeriodoSolicitadoReport();
		}
		return lista.toArray();	
	}
	public static Map<Integer,String>  getAllClientes(){
		List<Cliente> lista =ClienteConnector.getAllClientes();
		Map<Integer,String> clientesMap=new HashMap<Integer, String>();
		
		 for(Iterator it = lista.iterator();it.hasNext();){
			 Cliente cred = (Cliente) it.next();
	    	   clientesMap.put(new Integer(cred.getCkCliente().getIdCliente()), cred.getNombreCliente());
	     }
		return clientesMap;	
	}
	public static Map<Integer,String>  getAllEjecutivos(){
		List<Ejecutivo> lista =EjecutivoConnector.getAllEjecutivos();
		Map<Integer,String> clientesMap=new HashMap<Integer, String>();
		
		 for(Iterator<Ejecutivo> it = lista.iterator();it.hasNext();){
			 Ejecutivo ejec = (Ejecutivo) it.next();
	    	   clientesMap.put(new Integer(ejec.getCkejecutivo().getIdEjecutivo()), ejec.getNombres()+" "+ejec.getApellidoPaterno()+" "+ejec.getApellidoMaterno());
	     }
		return clientesMap;	
	}
	
	// fin consultaCatalogos
	
	
	public static void main(String []a) throws ParseException{
			List<Object []> lista;
			lista =  ReportConnectors.getPagosByPeriodoForComisions("05/05/2008","01/01/2011");
			Map<Integer,String> mapClientes = ReportConnectors.getAllClientes();
		
			String []header =new String[]{"Sucursal", "Crédito","Fecha", "Pago","Intereses","Comisión Mexcad","Comer 1","Comer 2"};
			float []tamCols =new float[]{1 ,2.5f,2.5f, 1.5f, 1.5f, 1.5f, 1.5f   };
			List<DataType []> listadoDatos = new ArrayList<DataType []>();

			for(Iterator<Object []> it = lista.iterator();it.hasNext();){
				Object []obj = it.next();
				
					DataType []datos = new DataType[header.length];
					
					 datos[0]= new DataType();
					 datos[0].setAlignMode(Element.ALIGN_CENTER);
					 datos[0].setData(mapClientes.get((Integer)obj[1]));
					 datos[0].setDataType(DataType.STRING_TYPE);

					 datos[1]= new DataType();
					 datos[1].setAlignMode(Element.ALIGN_LEFT);
					 datos[1].setData((Integer)obj[2]);
					 datos[1].setDataType(DataType.STRING_TYPE);

					 datos[2]= new DataType();
					 datos[2].setAlignMode(Element.ALIGN_CENTER);
					 datos[2].setData(Formatter.getStringFromDate((Date)obj[3]));
					 datos[2].setDataType(DataType.STRING_TYPE);

					 datos[3]= new DataType();
					 datos[3].setAlignMode(Element.ALIGN_CENTER);
					 datos[3].setData(((java.math.BigDecimal)obj[4]).doubleValue());
					 datos[3].setDataType(DataType.CURRENCY_TYPE);

					 datos[4]= new DataType();
					 datos[4].setAlignMode(Element.ALIGN_RIGHT);
					 datos[4].setData(((java.math.BigDecimal)obj[5]).doubleValue());
					 datos[4].setDataType(DataType.CURRENCY_TYPE);

					 double intereses = ((java.math.BigDecimal)obj[5]).doubleValue();
					 double comision=((java.math.BigDecimal)obj[6]).doubleValue()/100;

					 datos[5]= new DataType();
					 datos[5].setAlignMode(Element.ALIGN_RIGHT);
					 datos[5].setData(intereses*comision);
					 datos[5].setDataType(DataType.CURRENCY_TYPE);

					 comision=((java.math.BigDecimal)obj[7]).doubleValue()/100;

					 datos[6]= new DataType();
					 datos[6].setAlignMode(Element.ALIGN_RIGHT);
					 datos[6].setData(intereses*comision);
					 datos[6].setDataType(DataType.CURRENCY_TYPE);

					 comision=((java.math.BigDecimal)obj[8]).doubleValue()/100;

					 datos[7]= new DataType();
					 datos[7].setAlignMode(Element.ALIGN_RIGHT);
					 datos[7].setData(intereses*comision);
					 datos[7].setDataType(DataType.CURRENCY_TYPE);
					 
					 
					 listadoDatos.add(datos);
			
			}
			
		
	
		
	//	System.out.println(listado.get(lista.get(0).getIdPeriodoSolicitado()).getDescPeriodoSolicitado());
		
		
	}
	//  FinColocacionCartera
	
	
}